﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using MacomberMapSystem.Common.Database;
using System.Data.Common;
using MacomberMapSystem.Common.Serialization;
using System.IO;

namespace MacomberMapSystem.Common.User_Interfaces.Database
{
    /// <summary>
    /// (C) 2012, Michael E. Legatt, Ph.D., Electric Reliability Council of Texas, Inc.
    /// This class provides an interface for posting of the models
    /// </summary>
    public partial class frmModelPosting : DockContent
    {
        private SortedDictionary<int, MM_Database_Model> SortedModels = new SortedDictionary<int, MM_Database_Model>();
        private Dictionary<MM_Database_Model, ListViewItem> ModelItems = new Dictionary<MM_Database_Model, ListViewItem>();


        private MM_Repository Repository;
        /// <summary>
        /// Initialize our model posting form
        /// </summary>
        /// <param name="Models">Our collection of models</param>
        /// <param name="Repository"></param>
        public frmModelPosting(Dictionary<int, MM_Database_Model> Models, MM_Repository Repository)
        {
            InitializeComponent();
            this.Repository = Repository;
            foreach (MM_Database_Model Model in Models.Values)
                SortedModels.Add(-Model.ID, Model);

            foreach (MM_Database_Model Model in SortedModels.Values)
                AddModel(Model);
        }

        /// <summary>
        /// Add a model to our list view
        /// </summary>
        /// <param name="Model"></param>
        private void AddModel(MM_Database_Model Model)
        {
            ListViewItem lvI = lvModels.Items.Add(Model.Name);
            lvI.Tag = Model;
            lvI.SubItems.Add("0").Tag = 0;
            lvI.SubItems.Add(Model.IdealNum.ToString("#,##0"));
            lvI.SubItems.Add("");
            lvI.SubItems.Add("");
            if (Model.ValidationEnd.ToOADate() != 0)
                lvI.SubItems.Add((Model.ValidationStart.ToString() + " (" + (Model.ValidationEnd - Model.ValidationStart).ToString() + ")"));
            else
                lvI.SubItems.Add(Model.ValidationStart.ToString());
            ModelItems.Add(Model, lvI);

        }


        /// <summary>
        /// Go through and update our timer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmrUpdate_Tick(object sender, EventArgs e)
        {
            tmrUpdate.Enabled = false;            
            /*List<int> ModelsToAdd = new List<int>();
            MM_Database_Model FoundModel;
            using (DbCommand dCmd = Repository.Db.CreateCommand("SELECT ID, IDEALNUM, POSTEDON, POSTEDBY, VALIDATIONSTART, VALIDATIONEND FROM MM_DATABASE_MODEL"))
            using (DbDataReader dRd = dCmd.ExecuteReader())
                while (dRd.Read())
                    if (!SortedModels.TryGetValue(-1 * Convert.ToInt32(dRd["ID"]), out FoundModel))
                        ModelsToAdd.Add(Convert.ToInt32(dRd["ID"]));
                    else                    
                    try {
                        int FileCount = int.MaxValue;
                        DirectoryInfo dI;
                        foreach (String SubFolder in "dtspsm,rtnet,scada,smtnet,stnet".Split(','))
                            if ((dI = new DirectoryInfo(Path.Combine(FoundModel.FullPath, "Export\\" + SubFolder))).Exists)
                                FileCount = Math.Min(FileCount, dI.GetFiles("*.fgdisplay").Length);
                        CheckChangeModel(FoundModel, FileCount, dRd["IDEALNUM"], dRd["POSTEDON"], dRd["POSTEDBY"], dRd["ValidationStart"], dRd["VALIDATIONEND"]);
                    }
            catch 
                    {
            }*/
        }

        /// <summary>
        /// Check to determine whether a model value has changed
        /// </summary>
        /// <param name="FileCount"></param>
        /// <param name="FoundModel"></param>
        /// <param name="IdealNum"></param>
        /// <param name="PostedBy"></param>
        /// <param name="PostedOn"></param>
        /// <param name="ValidationEnd"></param>
        /// <param name="ValidationStart"></param>
        private void CheckChangeModel(MM_Database_Model FoundModel,  int FileCount, Object IdealNum, Object PostedOn, Object PostedBy, Object ValidationStart, Object ValidationEnd)
        {
            bool Include = false;
            ListViewItem lvI = ModelItems[FoundModel];
            if (FileCount != (Int32)lvI.SubItems[1].Tag)
            {
                lvI.SubItems[1].Text = FileCount.ToString("#,##0");
                lvI.SubItems[1].Tag = FileCount;
                Include = true;
            }


            if (IdealNum is DBNull == false && Convert.ToInt32(IdealNum) != FoundModel.IdealNum)
            {
                FoundModel.IdealNum = Convert.ToInt32(IdealNum);
                lvI.SubItems[2].Text = FoundModel.IdealNum.ToString("#,##0");
                Include = true;
            }

            if (PostedOn is DateTime && Convert.ToDateTime(PostedOn) != FoundModel.PostedOn)
            {
                FoundModel.PostedOn = Convert.ToDateTime(PostedOn);
                lvI.SubItems[3].Text = FoundModel.PostedOn.ToString();
                Include = true;
            }

            if (PostedBy is DBNull == false && (FoundModel.PostedBy == null || FoundModel.PostedBy.ID != Convert.ToInt32(PostedBy)))
            {
                FoundModel.PostedBy = Repository.User_Collection[Convert.ToInt32(PostedBy)];
                lvI.SubItems[4].Text = FoundModel.PostedBy.Nickname;
                Include = true;
            }


            if (Include)
                UpdateModel(FoundModel);
        }

        private delegate void SafeUpdateModel(MM_Database_Model Model);
        /// <summary>
        /// Update our model information
        /// </summary>
        /// <param name="Model"></param>
        private void UpdateModel(MM_Database_Model Model)
        {
            if (lvModels.InvokeRequired)
                lvModels.Invoke(new SafeUpdateModel(UpdateModel), Model);
            else
            {
                ListViewItem FoundModel = null;
                foreach (ListViewItem lvi in lvModels.Items)
                    if (lvi.Tag == Model)
                        FoundModel = lvi;
               
            }
        }
    }
}
